#include "CPlayer.h"
//#include "CHomingWeapon.h"
//#include "CBounceWeapon.h"
//#include "CLaserWeapon.h"
#include "CGameApp.h"

extern float VIEW_WIDTH;
extern float VIEW_HEIGHT;
extern bool IsItemUpdating(CSpecialItem* item);

//to be used by remove_if only, returns true if item is done updating
//bool IsItemUpdating( CSpecialItem* item )
//{
//	if( item == NULL ) { return true; }
//		//return true if the item should be removed
//	if( item->GetUpdating() == false )
//	{
//		delete item;
//		return true;
//	}
//	return false;
//};

CPlayer::CPlayer()
:CEntity(),
m_bIsJumping(false),
m_fJumpRate(0.3f),
m_fJumpTimer(0),
m_fJumpTime(0),
FriendLevel(5),
BaseSpeed(0),
JumpForce(30.0f),
AirTime(0.5f),
PrimaryWeapon(NULL),
SecondaryWeapon(NULL)
{
//Items(0)

	PrimaryWeapon = new CWeapon(5,1);//BounceWeapon(20,4);//LaserWeapon( 1, 2);//bounce 30,2
	PrimaryWeapon->Attach( this ); //attaches the player to the weapon
	PrimaryWeapon->SpreadAngle = 15.0f;
	PrimaryWeapon->RateOfFire = 5.0f;//6
	PrimaryWeapon->SetBulletSpeed( 5 );

	SecondaryWeapon = new CHealerWeapon(5,2);//BounceWeapon(20,4);//LaserWeapon( 1, 2);//bounce 30,2
	SecondaryWeapon->Attach( this ); //attaches the player to the weapon
	SecondaryWeapon->SpreadAngle = 15.0f;
	SecondaryWeapon->RateOfFire = 5.0f;//6
	SecondaryWeapon->SetBulletSpeed( 5 );
	
	SetType( "CPlayer" );
}

CPlayer::~CPlayer()
{
	if( PrimaryWeapon ) { delete PrimaryWeapon; }
	if( SecondaryWeapon ) { delete SecondaryWeapon; }
	list< CSpecialItem* >::iterator i;
	for( i = Items.begin(); i != Items.end(); i++ )
	{
		delete (*i);
		
	}
	Items.clear();
}

void CPlayer::Render()
{
	CEntity::Render();
	PrimaryWeapon->Render(); //renders the bullets
	SecondaryWeapon->Render();
	
	
	list< CSpecialItem* >::iterator i;
	for( i = Items.begin(); i != Items.end(); i++ )
	{
		if( (*i) == NULL ) { continue; }
			
		(*i)->Render();	
	}
}

void CPlayer::Update()
{
	//player x and y velocities to store which direction the player is travelling in
	int xvel = 0;
	int yvel = 0;

	if( pParent->KeyState['r'] == true )
	{
		//cout << GetAlive() << " " << false << endl;
		if( GetAlive() == false )
		{
			Respawn();
		}
	}

	if( GetAlive() )
	{  
		CGameApp* game = pParent;
		//if( GetPosX() != GetOldPosX() )// || GetPosY() != GetOldPosY() )
		//{
		//	SetOldPosX( GetPosX() );//, GetPosY() );
		//}
		bool setoldpos = false;
		//float tempoldx = 0;
		//float tempoldy = 0;
		//the player can access the keystate array via the pParent pointer
		//if( game->KeyState['a'] == true )	{ RotateFaceAngleBy( game->DeltaTime*GetRotateSpeed()*360 ); }//Player->MovePosX( -DeltaTime*Player->GetSpeed() ); }
		//if( game->KeyState['s'] == true || game->KeyState['k'] == true )
		//{
		//	if( setoldpos == false )
		//	{
		//		SetOldPos( GetPosX(), GetPosY() );
		//		setoldpos = true;
		//	}
		//	//cout << GetVelX() << " " << GetVelY() << endl;
		//	MovePosY( -game->DeltaTime*GetSpeed()*GetVelY() ); //-DeltaTime*Player->GetSpeed()*Player->GetVelY() );//
		//	MovePosX( -game->DeltaTime*GetSpeed()*GetVelX() );
		//}
		//if( game->KeyState['w'] == true || game->KeyState['i'] == true )
		//{
		//	if( setoldpos == false )
		//	{
		//		SetOldPos( GetPosX(), GetPosY() );
		//		setoldpos = true;
		//	}
		//	//SetOldPos( GetPosX(), GetPosY() );
		//	//cout << GetVelX() << " " << GetVelY() << endl;
		//	MovePosY( game->DeltaTime*GetSpeed()*GetVelY() );
		//	MovePosX( game->DeltaTime*GetSpeed()*GetVelX() );
		//}
		//if( game->KeyState['d'] == true )	{ RotateFaceAngleBy( -game->DeltaTime*GetRotateSpeed()*360 ); }//MovePosX( DeltaTime*Player->GetSpeed() ); }
		
		if( game->KeyState['z'] == true ) { Jump(); }
		if( game->ArrowState[GLUT_KEY_RIGHT] == true ) 
		{
			if( setoldpos == false )
			{
				SetOldPos( GetPosX(), GetPosY() );
				setoldpos = true;
			}
			//SetOldPos( GetPosX(), GetPosY() );
			if( game->KeyState['x'] == false && game->KeyState['s'] == false )
			{
				MovePosX( game->DeltaTime * cos((GetFaceAngle()-90) * 0.0174533) * GetSpeed() );
				MovePosY( game->DeltaTime * sin((GetFaceAngle()-90) * 0.0174533) * GetSpeed() );
			}
			SetFaceAngle( 90 );

			switch( FriendLevel )
			{
			case 0:
			case 1:
				SetTexture( pParent->PlayerTextureOne.texID );
				break;
			case 2:
			case 3:
				SetTexture( pParent->PlayerTextureTwo.texID );
				break;
			case 4:
			case 5:
				SetTexture( pParent->PlayerTextureThree.texID );
				break;
			case 6:
			case 7:
				SetTexture( pParent->PlayerTextureFour.texID );
				break;
			case 8:
			case 9:
			case 10:
				SetTexture( pParent->PlayerTextureFive.texID );
				break;
			default:
				break;

			}


			//SetTexture( pParent->PlayerTexture.texID );
			//MovePosY( game->DeltaTime*GetSpeed()*GetVelY() );//
			//MovePosX( game->DeltaTime*GetSpeed()*GetVelX() );//
		}
		if( game->ArrowState[GLUT_KEY_LEFT] == true ) 
		{
			if( setoldpos == false )
			{
				SetOldPos( GetPosX(), GetPosY() );
				setoldpos = true;
			}
			//SetOldPos( GetPosX(), GetPosY() );
			if( game->KeyState['x'] == false && game->KeyState['s'] == false )
			{
				MovePosX( -game->DeltaTime * cos((GetFaceAngle()+90) * 0.0174533) * GetSpeed() );
				MovePosY( -game->DeltaTime * sin((GetFaceAngle()+90) * 0.0174533) * GetSpeed() );
			}
			SetFaceAngle( 270 );
			SetTexture( pParent->PlayerTextureOne.texID );
			switch( FriendLevel )
			{
			case 0:
			case 1:
				SetTexture( pParent->PlayerTextureOneMirror.texID );
				break;
			case 2:
			case 3:
				SetTexture( pParent->PlayerTextureTwoMirror.texID );
				break;
			case 4:
			case 5:
				SetTexture( pParent->PlayerTextureThreeMirror.texID );
				break;
			case 6:
			case 7:
				SetTexture( pParent->PlayerTextureFourMirror.texID );
				break;
			case 8:
			case 9:
			case 10:
				SetTexture( pParent->PlayerTextureFiveMirror.texID );
				break;
			default:
				break;

			}
		}
		if( game->KeyState['x'] == true )
		{
			cout << GetJumpTime() << endl;
			if( GetJumpTime() <= 0.1f )
			{
				FireBullet();
			}
		}
		if( game->KeyState['s'] == true )
		{
			if( GetJumpTime() <= 0.1f )
			{
				SecondaryWeapon->FireBullet();
			}
		}
		
		MovePosY( game->DeltaTime * -15.0f );
		//added for xvel and yvel
/*
		if( game->KeyState['j'] == true || game->KeyState['l'] == true ) 
		{
			if( game->KeyState['j'] == true ) { xvel = -1; }
			if( game->KeyState['l'] == true ) { xvel =  1; }
			if( game->KeyState['l'] == true && game->KeyState['j'] == true ) { xvel = 0; }
		}

		if( game->KeyState['i'] == true || game->KeyState['k'] == true ) 
		{
			if( game->KeyState['k'] == true ) { yvel = -1; }
			if( game->KeyState['i'] == true ) { yvel =  1; }
			if( game->KeyState['i'] == true && game->KeyState['k'] == true ) { yvel = 0; }
		}
*/




		if( game->KeyState['o'] == true )	{ SetSize( GetSize() * 1.01f ); }
		if( game->KeyState['p'] == true )	{ SetSize( GetSize() * 0.99f ); }//Player->GetSize() - 0.08f ); }
		//if( game->KeyState['q'] == true )	{ PrimaryWeapon->SpreadAngle -= 0.1f; }
		//if( game->KeyState['e'] == true )	{ PrimaryWeapon->SpreadAngle += 0.1f; }

		//if( game->KeyState['n'] == true )	{ game->GameSpeed += game->DeltaTime*0.5f; }
		//if( game->KeyState['m'] == true )	{ game->GameSpeed -= game->DeltaTime*0.5f; }

		if( game->KeyState['t'] == true )
		{
			CWeapon* wpn = new CWeapon( 15, 4 );
			//wpn->Attach( this );
			//load won't work unless it has a ship attached to it
			//wpn->Load();
			//wpn->SpreadAngle = 9.0f;
			//wpn->RateOfFire = 6.0f;
			EquipPrimary( wpn );
			//wpn->SetBulletSpeed( 1 );
		}
		if( game->KeyState['y'] == true )
		{
			CWeapon* wpn = new CWeapon( 15, 3 );
			//wpn->Attach( this );
			//load won't work unless it has a ship attached to it
			//wpn->Load();

			EquipPrimary( wpn );
			wpn->SpreadAngle = 6.0f;
			//wpn->SetBulletSpeed( 1 );
			wpn->RateOfFire = 4.0f;
			//wpn->SetBulletSpeed( 10.0f );
		}
		if( game->KeyState['u'] == true )
		{
			CWeapon* wpn = new CWeapon( 15, 3 );
			
			//wpn->Attach( this );
			//load won't work unless it has a ship attached to it
			//wpn->Load();
			//wpn->SpreadAngle = 20.0f;
			//wpn->RateOfFire = 6.0f;
			EquipPrimary( wpn );
			//wpn->SetBulletSpeed( 1 );
			wpn->RateOfFire = 2;
		}
		if( game->KeyState['g'] == true )
		{
			CWeapon* wpn = new CWeapon( 3 , 3 );
			//wpn->Attach( this );
			//wpn->Load();
			EquipPrimary( wpn );
		}

		//if( game->KeyState[32] == true ) //spacebar
		{
			//FireBullet();
			//for( int i = 0; i < game->NumEnemies; i++ )
			//{
			//	game->Enemy[i]->FireBullet();
			//}
		}
	}
	
	if( FriendLevel > 10 ) { FriendLevel = 10; }
	if( FriendLevel < 0 )  { FriendLevel = 0; }
	SetSpeed( 5 + FriendLevel );
	JumpForce = 15 + FriendLevel*5.0f; 
	PrimaryWeapon->SetDamage( (10-FriendLevel)/3 * 3 );
	JumpUpdate();
	//switch( FriendLevel )
	//{
	//case 0:
	//case 1:
	//	SetTexture( pParent->PlayerTextureOne.texID );
	//	if( pParent->ArrowState[GLUT_KEY_LEFT] == true )
	//	{
	//		SetTexture( pParent->PlayerTextureOneMirror.texID );
	//	}
	//	break;
	//case 2:
	//case 3:
	//	SetTexture( pParent->PlayerTextureTwo.texID );
	//	if( pParent->ArrowState[GLUT_KEY_LEFT] == true )
	//	{
	//		SetTexture( pParent->PlayerTextureTwoMirror.texID );
	//	}
	//	break;
	//case 4:
	//case 5:
	//	SetTexture( pParent->PlayerTextureThree.texID );
	//	if( pParent->ArrowState[GLUT_KEY_LEFT] == true )
	//	{
	//		SetTexture( pParent->PlayerTextureThreeMirror.texID );
	//	}
	//	break;
	//case 6:
	//case 7:
	//	SetTexture( pParent->PlayerTextureFour.texID );
	//	if( pParent->ArrowState[GLUT_KEY_LEFT] == true )
	//	{
	//		SetTexture( pParent->PlayerTextureFourMirror.texID );
	//	}
	//	break;
	//case 8:
	//case 9:
	//case 10:
	//	SetTexture( pParent->PlayerTextureFive.texID );
	//	if( pParent->ArrowState[GLUT_KEY_LEFT] == true )
	//	{
	//		SetTexture( pParent->PlayerTextureFiveMirror.texID );
	//	}
	//	break;
	//default:
	//	break;

	//}

	//order the blocks according to the distance from the player
//	for( int i = 0; i < pParent->NumBlocks; i++ )
//	{
//		pParent->Block[i]->SetDistanceToPlayer( GetDistanceTo( pParent->Block[i] ) );
//	}

	//int startloop = 0;
	//int endloop   = pParent->NumBlocks;
	//int increment = 1;
	//if( GetOldPosX() > GetPosX() )//xvel == -1 || ( yvel == 1 && GetFaceAngle() > 90 && GetFaceAngle() < 270 ) )
	//{
	//	startloop = pParent->NumBlocks-1;
	//	endloop	  = -1;
	//	increment = -1;
	//}

//////////////////////////////////////////////////
//the problem is related to block order, reversing it reverses the x axis problem
//adding values to setoldpos doesn't help because movement resets those
//which means changing the old positions only affects collision checks in the for loop for the next blocks




	pParent->SortLevelBlocks( this );

	float newx = 1000;
	float newy = 1000;
	float minx,maxx,miny,maxy,cr,bminx,bmaxx,bminy,bmaxy;
	float oldminx,oldmaxx,oldminy,oldmaxy;

	for( int i=0; i < 3/*pParent->NumBlocks*/; i++ )
	//for( int i=startloop; i != endloop; i += increment ) 
	//for( int i=pParent->NumBlocks-1; i >=0; i-- )
	{
		if( pParent->Block[i]->GetAlive() == false ) { continue; }
		minx = pParent->Block[i]->GetPosX() - pParent->Block[i]->GetRadius();
		maxx = pParent->Block[i]->GetPosX() + pParent->Block[i]->GetRadius();
		miny = pParent->Block[i]->GetPosY() - pParent->Block[i]->GetRadius();
		maxy = pParent->Block[i]->GetPosY() + pParent->Block[i]->GetRadius();
		oldminx = pParent->Block[i]->GetOldPosX() - pParent->Block[i]->GetRadius();
		oldmaxx = pParent->Block[i]->GetOldPosX() + pParent->Block[i]->GetRadius();
		oldminy = pParent->Block[i]->GetOldPosY() - pParent->Block[i]->GetRadius();
		oldmaxy = pParent->Block[i]->GetOldPosY() + pParent->Block[i]->GetRadius();

		if( GetAlive() == false ) { continue; }
		cr    = GetCollisionRadius();
		bminx = GetPosX() - cr;
		bmaxx = GetPosX() + cr;
		bminy = GetPosY() - cr;
		bmaxy = GetPosY() + cr;
		if( bminx >= maxx ) { continue; } //bullet to the right, no collision
		if( bmaxx <= minx ) { continue; } //bullet to the left, no collision
		if( bminy >= maxy ) { continue; } //bullet above, no collision
		if( bmaxy <= miny ) { continue; } //bullet below, no collision
		//collision, do something
		//if( GetOldPosX()-cr > oldmaxx )//|| (GetOldPosX()+cr) < oldminx )
		//{
		//	newy = maxy + cr;
		if( GetOldPosY() > oldmaxy && GetOldPosX() < oldminx )//top left corner entry
		{
//			cout << "top left" << " " << i << endl;
			//SetOldPos( GetPosX(), GetPosY() );
			if( fabs( pParent->Block[i]->GetOldPosY() - GetOldPosY() ) > fabs( pParent->Block[i]->GetOldPosX() - GetOldPosX() ) )
			{
				ResetJump();
				SetPosY( maxy + cr );
			}
			else
			{
				//SetPosY( maxy + cr );
				SetPosX( minx - cr );
			}
			//SetPosY( maxy + cr );
			SetOldPos( GetPosX(), GetPosY() );
			continue;
			//need to check all the blocks again after setting the position
			//put the for loop inside a while loop and only exit if no blocks are occupied
		}
		if( GetOldPosY() > oldmaxy && GetOldPosX() > oldmaxx )//top right corner entry
		{
//			cout << "top right" << " " << i << endl;
			//SetOldPos( GetPosX(), GetPosY() );
			if( fabs( pParent->Block[i]->GetOldPosY() - GetOldPosY() ) > fabs( pParent->Block[i]->GetOldPosX() - GetOldPosX() ) )
			{
				ResetJump();
				SetPosY( maxy + cr );
			}
			else
			{
				//SetPosY( maxy + cr );
				SetPosX( maxx + cr );
			}
			//SetPosY( maxy + cr );
			SetOldPos( GetPosX(), GetPosY() );
			continue;
			//need to check all the blocks again after setting the position
			//put the for loop inside a while loop and only exit if no blocks are occupied
		}
		if( GetOldPosY() < oldminy && GetOldPosX() < oldminx )//bottom left corner entry
		{
//			cout << "bottom left" << " " << i << endl;
			//SetOldPos( GetPosX(), GetPosY() );
			if( fabs( pParent->Block[i]->GetOldPosY() - GetOldPosY() ) > fabs( pParent->Block[i]->GetOldPosX() - GetOldPosX() ) )
			{
				StopJump();
				SetPosY( miny - cr );
			}
			else
			{
				SetPosX( minx - cr );
			}
			//SetPosY( miny - cr );
			SetOldPos( GetPosX(), GetPosY() );
			continue;
			//need to check all the blocks again after setting the position
			//put the for loop inside a while loop and only exit if no blocks are occupied
		}
		if( GetOldPosY() < oldminy && GetOldPosX() > oldmaxx )//bottom right corner entry
		{
//			cout << "bottom right" << " " << i << endl;
			//SetOldPos( GetPosX(), GetPosY() );
			if( fabs( pParent->Block[i]->GetOldPosY() - GetOldPosY() ) > fabs( pParent->Block[i]->GetOldPosX() - GetOldPosX() ) )
			{
				StopJump();
				SetPosY( miny - cr );
			}
			else
			{
				SetPosX( maxx + cr );
			}
			//SetPosY( miny - cr );
			SetOldPos( GetPosX(), GetPosY() );
			continue;
			//need to check all the blocks again after setting the position
			//put the for loop inside a while loop and only exit if no blocks are occupied
		}
/*
			if( GetOldPosY() > oldmaxy || GetOldPosY() < oldminy )
			{
				if( yvel < 0 ) { cout << "down" << " " << i << endl; SetOldPosY( GetPosY() ); SetPosY( maxy + cr ); } 
				if( yvel > 0 ) { cout << "up" << " " << i << endl; SetOldPosY( GetPosY() ); SetPosY( miny - cr ); }
			}
			else//if( GetOldPosX() > oldmaxx || GetOldPosX() < oldminx )
			{
				if( xvel < 0 ) { cout << "left" << " " << i << endl; SetOldPosX( GetPosX() ); SetPosX( maxx + cr ); } 
				if( xvel > 0 ) { cout << "right" << " " << i << endl; SetOldPosX( GetPosX() ); SetPosX( minx - cr ); }
			}
*/

		if( GetOldPosY() > oldmaxy || GetOldPosY() < oldminy)// && (GetOldPosX() < oldmaxx && GetOldPosX() > oldminx) )
		{
			if( GetOldPosY() > oldmaxy )	{ /*cout << "moving down\t" << i/*xvel << " " << yvel << endl;*/ SetOldPosY( maxy + cr ); SetPosY( maxy + cr ); ResetJump();}//newy = maxy + cr; }//continue;}
			if( GetOldPosY() < oldminy )	{ /*cout << "moving up\t" << i/*xvel << " " << yvel << endl;*/   SetOldPosY( miny - cr ); SetPosY( miny - cr ); StopJump(); }//newy = miny - cr; }//continue;}
		}
		else
		{
			if( GetOldPosX() > oldmaxx )	{ /*cout << "moving left\t" << i/*xvel << " " << yvel << endl;*/  SetOldPosX( maxx + cr ); SetPosX( maxx + cr ); }//newx = maxx + cr; }
			if( GetOldPosX() < oldminx )	{ /*cout << "moving right\t" << i/*xvel << " " << yvel << endl;*/ SetOldPosX( minx - cr ); SetPosX( minx - cr ); }// newx = minx - cr; }
		}


	}//next block

	for( int j = 0; j < pParent->NumPolygons; j++ )
	{
		
		CPolygon* poly = &pParent->Polygons[j];//PolyBlock;
		//check bounding box of polygon before getting down and dirty with the lines

		if( GetAlive() == false ) { continue; }
		if( poly->InBoundingBox( this ) == false ) { continue; }
		//float crr    = GetCollisionRadius();
		////bminx = GetPosX() - cr;
		////bmaxx = GetPosX() + cr;
		////bminy = GetPosY() - cr;
		////bmaxy = GetPosY() + cr;
		//if( GetPosX() - crr >= poly->Max.x ) { continue; } //player to the right, no collision
		//if( GetPosX() + crr <= poly->Min.x ) { continue; } //player to the left, no collision
		//if( GetPosY() - crr >= poly->Max.y ) { continue; } //player above, no collision
		//if( GetPosY() + crr <= poly->Min.y ) { continue; } //player below, no collision








		//CEntity* bullet = Bullets[x][y];
		Vector2d prev,curr;
		//loop through each line of the polygon and check for collision with the bullet
		for( int i = 0; i < poly->NumVectors+1; i++ )
		{
			
			//store the current vector
			curr = poly->Polygon[i% poly->NumVectors];
			if( i==0 ) { prev = curr; continue; }
			//got my line, time to test it against the player
			Vector2d vec = Vector2d( curr.x - prev.x , curr.y - prev.y );
			Vector2d norm = Vector2d( vec.y*-1, vec.x );
			//normalize it
			float length = sqrtf( norm.x * norm.x + norm.y * norm.y );
			norm.x /= length;
			norm.y /= length;


			//vec is the vector of the line, norm is the normalized normal of vec
			//need to test line collision between vec and the player

			//convex polygons only
			//Vector2d pvec = Vector2d( GetPosX() - GetOldPosX() , GetPosY() - GetOldPosY() );
			//Vector2d pstart = OldPos;
			//Vector2d pend	= Pos;

			//concave polygons only
			Vector2d pstart = Vector2d( GetOldPosX() /*+ ( -norm.x * GetCollisionRadius() )*/, GetOldPosY() /*+ ( -norm.y * GetCollisionRadius() )*/  );
			Vector2d pend   = Vector2d( GetPosX() + ( -norm.x * GetCollisionRadius() ), GetPosY() + ( -norm.y * GetCollisionRadius() )  );
			Vector2d pvec = Vector2d( pend.x - pstart.x , pend.y - pstart.y );

			//pstart and pend is the start and end point of player, pvec is the line from pstart to pend
			//prev and curr is the polygon lines start and end point, vec being the line from prev to curr
			//norm is the normal of vec, facing away from the polygon

			float f = ( vec.y * pvec.x ) - ( vec.x * pvec.y );
			Vector2d c = Vector2d( pend.x - curr.x , pend.y - curr.y ); // end points of the player and line
			float aa = ( vec.y * c.x ) - ( vec.x * c.y );
			float bb = ( pvec.y * c.x ) - ( pvec.x * c.y );

			bool s = true;
			if(f <= 0)
			{
				if(aa > 0 || bb > 0 || aa < f || bb < f )   { s = false; }
				//if(bb > 0)    { s = false; }
				//if(aa < f)    { s = false; }
				//if(bb < f)    { s = false; }
			}
			if( f > 0 )
			{
				if(aa < 0 || bb < 0 || aa > f || bb > f )   { s = false; }
				//if(aa < 0 )   { s = false; }
				//if(bb < 0)    { s = false; }
				//if(aa > f)    { s = false; }
				//if(bb > f)     { s = false; }
			}
			
			if( s == true ) //collision
			{
				if( norm.y > 0 ) { ResetJump(); }//the surface hit was the ground
				if( norm.y < 0 ) { StopJump(); }
				float contact = 1.0f - (aa/f);
				//cout << "collision at " << ((pvec.x) * contact) + pstart.x << " " << ((pvec.y) * contact) + pstart.y << endl;
				//Pos.x = ((pvec.x) * contact) + pstart.x;
				//Pos.y = ((pvec.y) * contact) + pstart.y;
	//			Vector2d norm = Vector2d( vec.y*-1, vec.x );
	//			//normalize it
	//			float length = sqrtf( norm.x * norm.x + norm.y * norm.y );
	//			norm.x /= length;
	//			norm.y /= length;
				float d = prev.x*norm.x + prev.y*norm.y; //distance from plane to origin
				//cout << "plane to origin " << d;
				//ax+ by+cz-d = distance from the point of collision to the polygon line
				float od = norm.x*pend.x + norm.y*pend.y - d;
				//cout << " distance from plane to collision " << od << endl;
				Pos.x += norm.x * -od;// + pend.x;
				Pos.y += norm.y * -od;// + pend.y;
				float newd = norm.x*Pos.x + norm.y*Pos.y - d; 
				//cout << "distance from plane to new vertex" << newd << endl;
				MovePosX( norm.x * 0.02f );
				//SetOldPosX( norm.x * 0.1f );
				MovePosY( norm.y * 0.02f );
				//SetOldPosY( norm.y * 0.1f );
				
			//////////	//cout << vec.x << " " << vec.y << " " << i << norm.x << " " << norm.y << endl;

			//////////	//cout << norm.x << " " << norm.y << " " << bvec.x << " " << bvec.y << endl;
			//////////	Vector2d u = Vector2d( 1*norm.x * (bvec.x * norm.x + bvec.y * norm.y) , 1*norm.y * (bvec.x * norm.x + bvec.y * norm.y) );
			//////////	Vector2d w = Vector2d( bvec.x - u.x, bvec.y - u.y );
			//////////	Vector2d newvec = Vector2d( w.x - u.x , w.y - u.y );
			//////////	//newvec.x *= 100;
			//////////	//newvec.y *= 100;
			//////////	length = sqrtf( newvec.x * newvec.x + newvec.y * newvec.y );
			//////////	newvec.x /= length;
			//////////	newvec.y /= length;
			//////////// bool only = true;
			////////////if( only == true )
			////////////{
			////////////	cout << "bullet direction     " << bvec.x << " " << bvec.y << endl;
			////////////	cout << "line normal          " << norm.x << " " << norm.y << endl;
			////////////	cout << "new bullet direction " << newvec.x << " " << newvec.y << endl;
			////////////	only = false;
			////////////}
			//////////	//cout << newvec.x << " " << newvec.y << endl;
			//////////	//bullet->SetFaceAngle( newvec.x, newvec.y );
			//////////	if( newvec.x < 0 )		{ bullet->m_fFaceAngle = ( (atan( newvec.y/newvec.x )*57.2958f)+180 ); }
			//////////	if( newvec.x >= 0 )		{ bullet->m_fFaceAngle = ( atan( newvec.y/newvec.x )*57.2958f ); }
			//////////	bullet->SetVel( newvec.x, newvec.y ); //norm.x, norm.y );
			//////////	bullet->MovePosX( norm.x * 0.01f );
			//////////	bullet->MovePosY( norm.y * 0.01f );
				//v is the bullet velocity vector
				//w is parallel to the wall
				//u is perpindicular to it
				//n is the normal
				//v2 is the new velocity vector for the bullet


				//bullet->Kill();
			}
			//bullet->GetPos = bullet->G->Get*out = 1.0 - (aa / f);
			//Point intersection = ((B2 - B1) * out) + B1;

			//bstart + bvec*t

			prev = curr;
		}

	}//next polygon


	//if( newx < 999 ) { SetOldPosX( GetPosX() ); SetPosX( newx ); }//SetOldPosX( newx ); }
	//if( newy < 999 ) { SetOldPosY( GetPosY() ); SetPosY( newy ); }//SetOldPosY( newy ); }

	float edge = pParent->WorldEdge;
	if( GetPosX() < -edge ) { SetPosX( -edge ); }
	if( GetPosX() >  edge ) { SetPosX(  edge ); }
	if( GetPosY() < -edge ) { SetPosY( -edge ); }
	if( GetPosY() >  edge ) { SetPosY(  edge ); }
	if( GetPosY() < -50   ) { Kill(); SetPosY( -50 + GetCollisionRadius() + 0.1f ); }

	//if( GetPosX() < VIEW_WIDTH  * -0.48f ) { SetPosX(VIEW_WIDTH *-0.48f); }
	//if( GetPosX() > VIEW_WIDTH  *  0.48f ) { SetPosX(VIEW_WIDTH * 0.48f); }
	//if( GetPosY() < VIEW_HEIGHT * -0.48f ) { SetPosY(VIEW_HEIGHT*-0.48f); }
	//if( GetPosY() > VIEW_HEIGHT *  0.48f ) { SetPosY(VIEW_HEIGHT* 0.48f); }


	UpdateAttachedItems();

	//if( pParent->KeyState['t'] == true )	{ RotateFaceAngleBy( pParent->DeltaTime*GetRotateSpeed()*360 ); }//Player->MovePosX( -DeltaTime*Player->GetSpeed() ); }
	CEntity::Update();

	PrimaryWeapon->Update();
	SecondaryWeapon->Update();

	
	
}

void CPlayer::Load()
{
	if( pParent == NULL ) { cout << "CPlayer load failed, no game attached" << endl; return; }
	SetAlive( true );
	SetHealth( 6 );
	SetDamage( 15 );
	SetFaceAngle( 90.0f );
	SetPos( 5.0f, 150.0f );
	SetOldPos( GetPosX(), GetPosY()-0.01f );
	//SetVel( 0.0f, 1.0f );
	SetSpeed( 8.5f );
	BaseSpeed = GetSpeed();
	SetRotateSpeed( 0.5f );
	SetSize( 2.0f );
	SetCollisionSize( 1.3f );
	SetTexture( pParent->PlayerTextureThree.texID );
	SetDamageTexture( pParent->PlayerMirrorTexture.texID );
	SetExplosionTexture( pParent->ExplosionTexture );
	PrimaryWeapon->SetGame( pParent );
	PrimaryWeapon->Load();
	SecondaryWeapon->SetGame( pParent );
	SecondaryWeapon->Load();
	//PrimaryWeapon->SetBulletSpeed( 1.0f );
}

void CPlayer::TakeDamage( float damage )
{
	SetHealth( GetHealth() - damage );
	StartDamageAnimation();
	if( GetHealth() <= 0 )
	{
		Kill();
		//PrimaryWeapon->Kill();
		//SetAlive( false );
		//StartExplosion();
	}
}

void CPlayer::Kill()
{
	SetAlive( false );
	StartExplosion();
	PrimaryWeapon->Kill();
	SecondaryWeapon->Kill();
//	RemoveAllItems();
}

void CPlayer::FireBullet()
{
	PrimaryWeapon->FireBullet();
	//pParent->audio->Play("fire");

}

void CPlayer::EquipPrimary( CWeapon* weapon )
{
	if( weapon == NULL ) { cout << "no weapon passed into CPlayer::EquipPrimary" << endl; return; }
	if( PrimaryWeapon )
	{	
		PrimaryWeapon->Kill();
		delete PrimaryWeapon;
		weapon->Attach( this );
		weapon->Load();
		PrimaryWeapon = weapon;
	}

}

void CPlayer::SetRateOfFire( float rate )
{
	if(PrimaryWeapon)
	{
		PrimaryWeapon->RateOfFire = rate;
	}
}

void CPlayer::Jump()
{
	if( GetJumpTimer() > 1/GetJumpRate() )
	{
		SetJumping( true );
		SetJumpTimer( 0 );
		SetJumpTime( 0 );
	}
	//cout << GetPosX() << endl;
}

void CPlayer::JumpUpdate()
{
	SetJumpTimer( pParent->DeltaTime + GetJumpTimer() );
	if( GetJumping() == false ) { return; }
	MovePosY( JumpForce*pParent->DeltaTime  );
	//move up really fast and move down at an ever increasing speed
	SetJumpTime( GetJumpTime() + pParent->DeltaTime );
	if( GetJumpTime() > AirTime )
	{
		SetJumpTime( 0 );
		//SetJumpTimer( 0 );
		SetJumping( false );
	}
}

void CPlayer::ResetJump()
{
	SetJumpTime( 0 );
	SetJumpTimer( 1/GetJumpRate() );
	SetJumping( false );
}

void CPlayer::StopJump()
{
	SetJumping(false);
	SetJumpTimer(0);
	SetJumpTime( 0 );

}

void CPlayer::Respawn()
{
	SetAlive( true );
	SetHealth( 6 );
	SetDamage( 15 );
	SetFaceAngle( 90.0f );
	SetPos( 5.0f, 120.0f );
	SetOldPos( GetPosX(), GetPosY()-0.01f );
	FriendLevel = 5;

}

void CPlayer::AttachItem( CSpecialItem* itemtoadd )
{
	//cout << "inAttachItem and pointer is " << itemtoadd << endl;
	if( itemtoadd )
	{
		itemtoadd->SetIsItemAttached( true );
		itemtoadd->SetUpdating(true);
		itemtoadd->AttachToHost( this );
		Items.push_back( itemtoadd );
	}
	//cout << "made it through players attachitem" << endl;
}

void CPlayer::UpdateAttachedItems()
{
	list< CSpecialItem* >::iterator i;
	for( i = Items.begin(); i != Items.end(); i++ )
	{
		if( (*i) == NULL ) { continue; }
		//cout << "at least it's attached" << endl;
		if( (*i)->GetIsItemAttached() )
		{
			//cout << "attached" << endl;
			(*i)->UpdateAttached();
		}
	}
	Items.remove_if( IsItemUpdating );
}

void CPlayer::RemoveItem( CSpecialItem* itemtoremove )
{
	if( itemtoremove )
	{
		delete itemtoremove;
		Items.remove( itemtoremove );
	}
}

void CPlayer::RemoveAllItems()
{
	list< CSpecialItem* >::iterator i;
	for( i = Items.begin(); i != Items.end(); i++ )
	{
		delete (*i);
		
	}
	Items.clear();

}







		//cout << "collision" << endl;
/*		float test = 0.03f * pParent->GameSpeed;
		
				//if( GetOldPosX()-cr < oldmaxx && GetOldPosX()+cr > oldminx )
				//if the y distance from player to block is > the x distance from player to block
				if( fabs(GetPosY() - pParent->Block[i]->GetPosY()) > fabs(GetPosX() - pParent->Block[i]->GetPosX()) )
				{
					//column collision, reverse the y
					//if( GetOldPosY() < GetPosY() || pParent->Block[i]->GetOldPosY() > pParent->Block[i]->GetPosY() )//moving up
					if( fabs( miny - GetPosY() ) < fabs( maxy - GetPosY() ) )
					//if( fabs( minx - GetPosX() ) < fabs( maxx - GetPosX() ) )
					{
						//newx = minx-cr-test;
						newy = miny-cr;//-test;
						cout << "moving up " << i << endl; //up
						//SetPosY( miny-cr-test );
						//break;
						continue;
					}
					//if(GetOldPosY() > GetPosY() || pParent->Block[i]->GetOldPosY() < pParent->Block[i]->GetPosY() )//moving down
					if( fabs( miny - GetPosY() ) >= fabs( maxy - GetPosY() ) )
					//if( fabs( minx - GetPosX() ) >= fabs( maxx - GetPosX() ) )
					{
						//newx = maxx+cr+test;
						//cout << "moving left " << i << endl;
						newy = maxy+cr;//+test;
						cout << "moving down " << i << endl;
						//SetPosY( maxy+cr+test );
						//break;
						continue;
					}
				}
				else
				{
					//if( GetOldPosY()-cr < oldmaxy && GetOldPosY()+cr > oldminy )
					if( fabs(GetPosY() - pParent->Block[i]->GetPosY()) <= fabs(GetPosX() - pParent->Block[i]->GetPosX()) )
					{
						//row collision, reverse the x
						//if( GetOldPosX() < GetPosX() || pParent->Block[i]->GetOldPosX() > pParent->Block[i]->GetPosX() )//moving up
						//if( GetOldPosX() < GetPosX() )//moving right
						if( fabs( minx - GetPosX() ) < fabs( maxx - GetPosX() ) )
						//if( fabs( miny - GetPosY() ) < fabs( maxy - GetPosY() ) )
						{
							//newy = miny-cr-test;
							//cout << "moving up " << i << endl;
							//cout << minx << "\t" << cr << endl;
							newx = minx-cr;//-test;
							cout << "moving right " << i << endl;
							//SetPosX( minx-cr-test );
							//break;
							continue;
						}
						//else
						{
							//if(GetOldPosX() > GetPosX() || pParent->Block[i]->GetOldPosX() < pParent->Block[i]->GetPosX() )
							//if(GetOldPosX() > GetPosX() )//moving left
							if( fabs( minx - GetPosX() ) >= fabs( maxx - GetPosX() ) )
							//if( fabs( miny - GetPosY() ) >= fabs( maxy - GetPosY() ) )
							{
								//newy = maxy+cr+test;
								//cout << "moving down " << i << endl;
								//cout << maxx << "\t" << cr << endl;
								newx = maxx+cr;//+test;
								cout << "moving left " << i << endl;
								//SetPosX( maxx+cr+test );
								//break;
							}
						}
					}
					else
					{
						cout << "yeah, that happened" << endl;
						newy = maxy+cr+test;
					}
				}           */